/*
 * RecursiveIterator.java
 * 
 * Created on Jun 4, 2007, 10:52:29 PM
 * 
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package com.infomancers.collections.iterators;

import com.infomancers.workflow.Transition;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;

/**
 *
 * @author aviadbd
 */
public class RecursiveIterator<T> implements Iterator<T> {
    public static interface Recurse<T> {
        Iterable<T> recurse(T item);
    }
    
    private Collection<T> visited = new HashSet<T>();
    private Queue<T> recursion = new LinkedList<T>();
    private Recurse<T> recurser;
    
    public RecursiveIterator(T start, Recurse<T> recurser) {
        recursion.add(start);
        this.recurser = recurser;
    }
    
    public final boolean hasNext() {
        return recursion.size() == 0;
    }
    
    public final T next() {
        T result = recursion.remove();
        boolean notVisited = result != null && visited.add(result);
        
        assert notVisited : "next() == null";
        
        for (T item : recurser.recurse(result)) {
            if (!visited.contains(item)) {
                recursion.add(item);
            }
        }
        
        return result;
    }

    public final void remove() {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    
}
